<template>
  <el-input
    :model-value="inputValue"
    :disabled="disabled"
    :clearable="clearable"
    :placeholder="placeholder"
    @blur="onChange"
    @keydown.enter="onChange"
    @input="onInput"
  >
    <template v-for="(_, name) in $slots" :key="name" #[name]>
      <slot :name="name" />
    </template>
  </el-input>
</template>
<script lang="ts">
import { ElInput, ElMessage } from 'element-plus';
import { inputNumberProps } from './types';
import { defineComponent, ref, toRefs, watch } from 'vue';
import NP from 'number-precision';

export default defineComponent({
  name: 'InputNumber',
  components: {
    ElInput,
  },
  props: inputNumberProps,
  emits: ['update:modelValue', 'change'],
  setup(props, { emit }) {
    const { min, max, precision, modelValue } = toRefs(props);
    const inputValue = ref<number | string>('');
    const onInput = (val: string) => {
      const newVal = String(val).trim();
      inputValue.value = newVal;
      emit('update:modelValue', newVal);
    };
    const isNullish = (v: any) => [null, undefined].includes(v);
    const onChange = async () => {
      let newVal: number | string = String(inputValue.value);
      if (inputValue.value !== '' && !Number.isNaN(Number(newVal))) {
        if (+newVal > max.value) {
          newVal = max.value;
        } else if (+newVal < min.value) {
          newVal = min.value;
        }
        newVal = NP.round(newVal, precision.value);
        inputValue.value = newVal;
      } else {
        // 内容不为空且格式错误时
        if (isNullish(inputValue.value)) {
          ElMessage.warning('内容格式必须为数字');
        }
        inputValue.value = '';
        newVal = '';
      }
      emit('update:modelValue', newVal);
      emit('change', newVal);
    };
    watch(
      () => modelValue.value,
      (val) => {
        if (val !== inputValue.value) {
          inputValue.value = val;
        }
      },
      {
        immediate: true,
      }
    );

    return {
      onInput,
      inputValue,
      onChange,
    };
  },
});
</script>
